package com.espirit.eap.conversion;

import java.math.BigDecimal;
import java.text.DecimalFormat;
import java.util.Map;

import javax.annotation.PostConstruct;
import javax.annotation.Resource;

import org.apache.struts2.util.StrutsTypeConverter;
import org.springframework.stereotype.Service;

import com.googlecode.cswish.struts.spring.CacheService;
import com.googlecode.cswish.struts.spring.CacheService.Wrapper;
import com.googlecode.cswish.util.FrameConstant;

@Service
public class BigDecimalConverter extends StrutsTypeConverter {

	private Wrapper<Integer> priceScale;
	
	private Wrapper<Integer> amountScale;
	
	@Resource
	private CacheService cacheService;
	
	@PostConstruct
	private void init() {
		priceScale = cacheService.newVar(Integer.class, 2);
		amountScale = cacheService.newVar(Integer.class, 2);
	}
	
	public void setPriceScale(int priceScale) {
		this.priceScale.set(priceScale);
	}

	public void setAmountScale(int amountScale) {
		this.amountScale.set(amountScale);
	}
	
	private DecimalFormat buildDecimalFormat(int scale) {
		StringBuilder pattern = new StringBuilder(2 + scale);
		pattern.append('0').append('.');
		for (int i = 0; i < scale; i++) {
			pattern.append('0');
		}
		DecimalFormat df = new DecimalFormat(pattern.toString());
		return df;
	}
	
	@Override
	public Object convertFromString(Map context, String[] values, Class toClass) {
		BigDecimal val = null;
		if (values != null && values.length > 0) {
			String value = values[0];
			if (value.length() > 0) {				
				val = new BigDecimal(values[0]);
			} else {
				val = BigDecimal.ZERO;
			}
		}
		return val;
	}

	@Override
	public String convertToString(Map context, Object o) {
		String val;
		if (o != null) {
			String propertyName = (String) context.get(FrameConstant.CONVERTER_PROPERTY);
			boolean isCurrency = propertyName != null && (propertyName.endsWith("price") || propertyName.endsWith("Price"));
			DecimalFormat df;
			if (isCurrency) {
				int scale = priceScale.get();
				df = buildDecimalFormat(scale);
			} else {
				boolean isAmount = propertyName != null && (
						propertyName.equals("balance") || propertyName.endsWith("amount") || propertyName.endsWith("Amount"));
				if (isAmount) {
					int scale = amountScale.get();
					df = buildDecimalFormat(scale);
				} else {
					if (propertyName.equals("factor") || propertyName.equals("model.factor")){
						df = new DecimalFormat("0.000000");
					} else {
						df = new DecimalFormat("0.00");
					}
				}
			}
			val = df.format(o); 
		} else {
			val = null;
		}
		return val;
	}
}
